package com.tacuati.ui;

import java.util.ArrayList;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import com.tacuati.content.Content;
import com.tacuati.content.Item;

public class ContentTreeModel implements TreeModel {
	private Content kindleContent;
	private ArrayList<TreeModelListener> treeModelListeners = new ArrayList<TreeModelListener>();

	public ContentTreeModel(Content kindleContent) {
		this.kindleContent = kindleContent;
	}

	@Override
	public Object getChild(Object parent, int index) {
		return ((ContentTreeNode) parent).getChild(index);
	}

	@Override
	public int getChildCount(Object parent) {
		return ((ContentTreeNode) parent).getChildCount();
	}

	@Override
	public int getIndexOfChild(Object parent, Object child) {
		return ((ContentTreeNode) parent).getIndexOfChild((ContentTreeNode) child);
	}

	@Override
	public Object getRoot() {
		return kindleContent;
	}

	@Override
	public boolean isLeaf(Object node) {
		return (node instanceof Item);
	}

	@Override
	public void addTreeModelListener(TreeModelListener l) {
		treeModelListeners.add(l);
	}

	@Override
	public void removeTreeModelListener(TreeModelListener l) {
		treeModelListeners.remove(l);
	}

	@Override
	public void valueForPathChanged(TreePath path, Object newValue) {
		ContentTreeNode p = (ContentTreeNode) path.getLastPathComponent();		
		ContentTreeNode parent = (ContentTreeNode) path.getParentPath().getLastPathComponent();
		int index = parent.getIndexOfChild(p);
		p.setNodeName(newValue.toString());
		
		TreeModelEvent e = new TreeModelEvent(this, path.getParentPath().getPath(), new int[] { index }, new Object[] { p });
		for (TreeModelListener listener : treeModelListeners) {
			listener.treeNodesChanged(e);
		}
	}

	public void reload() {
		TreeModelEvent e = new TreeModelEvent(this, new Object[] { kindleContent });

		for (TreeModelListener listener : treeModelListeners) {
			listener.treeStructureChanged(e);
		}
	}

	public void removeNodeFromParent(Item item, Object p) {
		ContentTreeNode parent = (ContentTreeNode) p;		
		int index = parent.getIndexOfChild((ContentTreeNode) item);
		((ContentTreeNode) parent).removeChild(index);

		Object[] parents;
		if (kindleContent.equals(p)){
			parents = new Object[]{p};
		} else {
			parents = new Object[]{kindleContent,p};		
		}
		TreeModelEvent e = new TreeModelEvent(this, parents, new int[] { index }, new Object[] { item });
		
		for (TreeModelListener listener : treeModelListeners) {
			listener.treeNodesRemoved(e);
		}
	}

	public void insertNodeInto(Item item, Object p) {
		ContentTreeNode parent = (ContentTreeNode) p;		
		int index = parent.getChildCount();
		((ContentTreeNode) parent).addChild(index,item);

		Object[] parents;
		if (kindleContent.equals(p)){
			parents = new Object[]{p};
		} else {
			parents = new Object[]{kindleContent,p};		
		}
		TreeModelEvent e = new TreeModelEvent(this, parents, new int[] { index }, new Object[] { item });
		
		for (TreeModelListener listener : treeModelListeners) {
			listener.treeNodesInserted(e);
		}
	}
}
